package com.atguigu.gmall.order.controller;

import com.alibaba.fastjson.JSON;
import com.atguigu.gmall.cart.client.CartFeignClient;
import com.atguigu.gmall.common.constant.MqConst;
import com.atguigu.gmall.common.result.Result;
import com.atguigu.gmall.common.service.RabbitService;
import com.atguigu.gmall.common.util.AuthContextHolder;
import com.atguigu.gmall.model.cart.CartInfo;
import com.atguigu.gmall.model.order.OrderDetail;
import com.atguigu.gmall.model.order.OrderInfo;
import com.atguigu.gmall.model.user.UserAddress;
import com.atguigu.gmall.order.service.OrderService;
import com.atguigu.gmall.order.service.impl.OrderServiceImpl;
import com.atguigu.gmall.product.client.ProductFeignClient;
import com.atguigu.gmall.user.client.UserFeignClient;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import java.math.BigDecimal;
import java.util.*;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ThreadPoolExecutor;

@RestController
@RequestMapping("api/order")
public class OrderApiController {

    @Autowired
    private UserFeignClient userFeignClient;

    @Autowired
    private CartFeignClient cartFeignClient;

    @Autowired
    private OrderService orderService;

    @Autowired
    private OrderServiceImpl orderServiceImpl;

    @Autowired
    private ProductFeignClient productFeignClient;

    @Autowired
    private ThreadPoolExecutor threadPoolExecutor;

    @Autowired
    private RabbitService rabbitService;

    /**
     * 用户下结算页面显示
     *
     * @param request
     * @return
     */
    @GetMapping("auth/trade")
    public Result<Map<String, Object>> trade(HttpServletRequest request) {
//        获取用户id
        String userId = AuthContextHolder.getUserId(request);
//        用户地址信息
        List<UserAddress> userAddressList = userFeignClient.findUserAddressListByUserId(userId);
//        订单信息表
        List<CartInfo> cartInfoList = cartFeignClient.getCartCheckedList(userId);

//        存储订单信息集合
        List<OrderDetail> orderDetailList = new ArrayList<>();
//        赋值订单明细信息表
        int totalNum = 0;
        for (CartInfo cartInfo : cartInfoList) {
            OrderDetail orderDetail = new OrderDetail();
            orderDetail.setSkuId(cartInfo.getSkuId());
            orderDetail.setSkuName(cartInfo.getSkuName());
            orderDetail.setImgUrl(cartInfo.getImgUrl());
            orderDetail.setSkuNum(cartInfo.getSkuNum());
            orderDetail.setOrderPrice(cartInfo.getSkuPrice());
            // 添加到集合
            orderDetailList.add(orderDetail);

//            计算总的数量
//            totalNum += orderDetail.getSkuNum();
        }
//        计算总的价格和数量
        OrderInfo orderInfo = new OrderInfo();
//        价格
        orderInfo.setOrderDetailList(orderDetailList);
//        数量
        orderInfo.sumTotalAmount();

        Map<String, Object> result = new HashMap<>();
        result.put("userAddressList", userAddressList);
        result.put("detailArrayList", orderDetailList);
        // 保存总金额
        result.put("totalNum", orderDetailList.size());
        result.put("totalAmount", orderInfo.getTotalAmount());

//        获取流水号,存储起来
        String tradeNo = orderService.getTradeNo(userId);
        result.put("tradeNo", tradeNo);

        return Result.ok(result);
    }

    /**
     * 提交订单
     *
     * @param orderInfo
     * @param request
     * @return
     */
    @PostMapping("auth/submitOrder")
    public Result submitOrder(@RequestBody OrderInfo orderInfo, HttpServletRequest request) {
        // 获取到用户Id
        String userId = AuthContextHolder.getUserId(request);
        orderInfo.setUserId(Long.parseLong(userId));
        // 验证通过，保存订单！

//        判断流水号是否一致
        String tradeNo = request.getParameter("tradeNo");
        boolean flag = orderService.checkTradeCode(userId, tradeNo);
        if (!flag) {
            return Result.fail().message("请刷新页面,不能重复提交订单");
        }

//        存储错误集合
        List<String> errorList = new ArrayList<String>();
//        存储异步编排集合
        List<CompletableFuture> futureList = new ArrayList<>();

//        删除redis中订单号
        orderService.deleteTradeNo(userId);

        List<OrderDetail> orderDetailList = orderInfo.getOrderDetailList();
        for (OrderDetail orderDetail : orderDetailList) {

//            使用异步编排    检查库存
            CompletableFuture<Void> countSkunInfoList = CompletableFuture.runAsync(() -> {
                //            判断库存
                boolean result = orderService.checkStock(orderDetail.getSkuId(), orderDetail.getSkuNum());
                if (!result) {
                    errorList.add(orderDetail.getSkuName() + "库存不够！");
                }
            }, threadPoolExecutor);
            futureList.add(countSkunInfoList);
//            判断价格是否一致
//            获取订单价格
            CompletableFuture<Void> skunPriceList = CompletableFuture.runAsync(() -> {
                BigDecimal orderPrice = orderDetail.getOrderPrice();
//            获取商品最新价格
                BigDecimal skuPrice = productFeignClient.getSkuPrice(orderDetail.getSkuId());
//            价格不一样
                if (orderPrice.compareTo(skuPrice) != 0) {
//                更改价格，购物车的价格
                    cartFeignClient.loadCartCache(userId);
                    errorList.add(orderDetail.getOrderPrice() + "价格有变动");
                }
            }, threadPoolExecutor);
//            添加到异步编排集合中
            futureList.add(skunPriceList);
        }

//        合并线程,将集合转化为数组
        CompletableFuture.allOf(futureList.toArray(new CompletableFuture[futureList.size()])).join();
//        判断是否出现异常
        if (errorList.size() > 0) {
//                返回错误提示信息,使用逗号进行拼接
            return Result.fail().message(StringUtils.join(errorList, ","));
        }
//        返回订单id
        Long orderId = orderService.saveOrderInfo(orderInfo);
//        使用延迟对列延迟24时未支付时取消订单
            rabbitService.sendOrder(MqConst.EXCHANGE_DIRECT_ORDER_CANCEL,
                    MqConst.ROUTING_ORDER_CANCEL,orderId,MqConst.DELAY_TIME_SMALL);
        return Result.ok(orderId);
    }


    /**
     * 内部调用获取订单
     * @param orderId
     * @return
     */
    @GetMapping("inner/getOrderInfo/{orderId}")
    public OrderInfo getOrderInfo(@PathVariable(value = "orderId") Long orderId){
        return orderService.getOrderInfo(orderId);
    }


    /**
     * 拆单业务
     * @param request
     * @return json数据
     */
    @RequestMapping("orderSplit")
    public String orderSplit(HttpServletRequest request){
//        获取传递的数据
        String orderId = request.getParameter("orderId");
        String wareSkuMap = request.getParameter("wareSkuMap");
//        根据数据拆分订单
   List<OrderInfo> orderInfoList = orderService.orderSplitOrder(orderId,wareSkuMap);

   List<Map> mapList = new ArrayList<>();

        for (OrderInfo orderInfo : orderInfoList) {
//            转为map集合数据
            Map map = orderService.initJsonMap(orderInfo);
            mapList.add(map);
        }

       return JSON.toJSONString(mapList);
    }

    /**
     * 提交 秒杀订单
     * @param orderInfo
     * @return
     */
    @PostMapping("inner/seckill/submitOrder")
    public Long submitOrder(@RequestBody OrderInfo orderInfo) {
        Long orderId = orderService.saveOrderInfo(orderInfo);
        return orderId;
    }

}

